import json
from datetime import datetime

from django.utils import timezone # 处理时间的工具
from django import http
from django.core.paginator import Paginator, EmptyPage


from django.shortcuts import render

from goods.models import GoodsCategory, GoodsVisitCount
# Create your views here.
from django.views import View

from contents.utils import get_categories
from goods.utils import get_breadcrumb
from goods.models import SKU
from meiduo_mall.utils.response_code import RETCODE






class DetailVisitView(View):
    """详情页面商品访问量"""
    def post(self,request,category_id):
        """记录分类商品访问量"""
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('缺少必传参数')

        # 获取今天的日期
        t = timezone.localtime()
        today_str = '%d-%02d-%02d' %(t.year,t.month,t.day)
        today_data = datetime.strptime(today_str,'%Y-%m-%d')

        try:
            # 查询今天该类别的商品访问量
            counts_data= category.goodsvisitcount_set.get(date=today_data)
        except GoodsVisitCount.DoesNotExist:
            # 如果该类别的商品在今天没有过访问记录，就新建一个访问记录
            counts_data = GoodsVisitCount()

        try:
            counts_data.category = category
            counts_data.count +=1
            counts_data.save()
        except Exception as e:
            return http.HttpResponseForbidden('服务器异常')
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})




class DetailView(View):
    """商品详情页"""
    def get(self,request,sku_id):
        # 获取当前sku信息
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request,'404.html')
        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建商品规格数据
        sku_specs =sku.specs.order_by('spec_id')
        sku_key=[]
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数的sku字典
        spec_sku_map={}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数 -sku字典
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        #获取当前商品的规格信息
        goods_specs= sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不在继续
        if len(sku_key) < len(goods_specs):
            return
        for index,spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index]=option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options


        # 渲染页面
        context= {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': goods_specs,
        }

        return render(request,'detail.html',context)



class HotGoodsView(View):
    """热销排行"""
    def get(self,request,category_id):
        """提供商品热销排行数据JSON"""
        # 根据销量倒序
        skus = SKU.objects.filter(category_id=category_id,is_launched=True).order_by('-sales')[:2]
        # 序列化
        hot_skus=[]
        for sku in skus:
            hot_skus.append({
                'id':sku.id,
                'default_image_url':sku.default_image.url,
                'name':sku.name,
                'price':sku.price
            })
        return http.JsonResponse({'code':RETCODE.OK, 'errmsg':'OK', 'hot_skus':hot_skus})





class ListView(View):
    """商品列表页"""
    def get(self, request, category_id, page_num):
        """查询并渲染商品列表页"""

        # 校验参数category_id的范围 ： 1111111111111111111111111111111
        try:
            # 三级类别
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('参数category_id不存在')

        # 获取sort(排序规则): 如果sort没有值，取'default'
        sort = request.GET.get('sort', 'default')
        # 根据sort选择排序字段，排序字段必须是模型类的属性
        if sort == 'price':
            sort_field = 'price' # 按照价格由低到高排序
        elif sort == 'hot':
            sort_field = '-sales' # 按照销量由高到低排序
        else: # 只要不是'price'和'-sales'其他的所有情况都归为'default'
            sort = 'default' # 当出现?sort=itcast 也把sort设置我'default'
            sort_field = 'create_time'

        # 查询商品分类
        categories = get_categories()

        # 查询面包屑导航：一级 -> 二级 -> 三级
        breadcrumb = get_breadcrumb(category)

        # 分页和排序查询：category查询sku,一查多,一方的模型对象.多方关联字段.all/filter
        skus = category.sku_set.filter(is_launched=True).order_by(sort_field)

        # 创建分页器
        # Paginator('要分页的记录', '每页记录的条数')
        paginator = Paginator(skus, 5) # 把skus进行分页，每页5条记录
        # 获取到用户当前要看的那一页（核心数据）
        try:
            page_skus = paginator.page(page_num) # 获取到page_num页中的五条记录
        except EmptyPage:
            return http.HttpResponseNotFound('Empty Page')
        # 获取总页数：前端的分页插件需要使用
        total_page = paginator.num_pages

        # 构造上下文
        context = {
            'category':category,
            'categories': categories,
            'breadcrumb': breadcrumb,
            'page_skus': page_skus,
            'total_page': total_page,
            'page_num': page_num,
            'sort': sort,
            'category_id': category_id
        }

        return render(request, 'list.html', context)